<?php

namespace app\systems\logic;

use app\data\util\Rabbitmq;
use think\facade\Request;
use app\admin\model\AdminModel;
use app\systems\model\SystemMqGroupModel;
use think\Model;
use app\admin\logic\BasicLogic;
use app\systems\logic\MqGroupLogic;
use app\systems\validate\SystemMqAdd;
use app\systems\validate\SystemMqCheck;
use think\facade\Validate;
use think\facade\Cache;
use think\facade\Db;

class SystemMqLogic extends BasicLogic
{

    //// 定义分组id,,,添加队列任务为节省查询数据库开支，需把ebay_mq_group对应的id做定义
    const MQ_GROUP_ONE = 1;    #代码过程中产生的队列任务：如导入导出等
    const MQ_GROUP_TWO = 2;    #定时任务产生的队列任务
    const TASK_MAX_RETRY_TIMES = 1;    //任务执行失败最大重试次数

    const MQ_IS_DELAY_QUEUE_NO = 0;
    const MQ_IS_DELAY_QUEUE_YES = 1;
    const MQ_IS_DELAY_QUEUE_MAP = [
        self::MQ_IS_DELAY_QUEUE_NO => '否',
        self::MQ_IS_DELAY_QUEUE_YES => '是',
    ];

    const GROUP_INFO_DATA_KEY = 'mq_group_data_';

    /**
     * 队列任务-列表
     * @author xx
     * @Date 2024/3/12 17:13
     */
    public function page_list_service($params)
    {
        $group_name = $params['group_name']??'';
        $queue_name = $params['queue_function']??'';
        $page          = $params['page']??'1';
        $limit       = $params['limit']??'10';
        $where= [];
        if($group_name){
            $where[]=['group_name','like','%'.$group_name.'%'];
        }
        if($queue_name){
            $where[]=['queue_name','like','%'.$queue_name.'%'];
        }
        $list = (new SystemMqGroupModel())
            ->where($where)
            ->limit(($page - 1) * $limit, $limit)
            ->select();
        $list = objectToArray($list);
        
        $count= (new SystemMqGroupModel())->where($where)->count();
        $data['list']  = $list;
        $data['total'] = $count;
        return $this->jsonMessage(200, true, '获取成功', $data);
    }


    /**
     * 查询返回队列组列表
     * @return mixed
     * @author xx
     * @Date 2024/3/12 17:13
     */
    public function get_mq_group_list()
    {
        # 查询运行服务器IP
        $list = (new SystemMqGroupModel())->where(['status' => 1])->select();
        return  objectToArray($list);
    }

    /**
     * 根据id获取数据
     * @param $id
     * @param $cache
     * @return mixed
     * @author xx
     * @Date 2024/3/12 17:13
     */
    public  function get_mq_group_by_id($id, $cache = '')
    {
        $key  = self::getCacheKey($id, self::GROUP_INFO_DATA_KEY);
        $list = Cache::store('redis')->get($key);
        if (!$list) {
            $list = (new SystemMqGroupModel())->where(['id' => $id])->find();
            $list = objectToArray($list);
            Cache::store('redis')->set($key,$list,7200);
        }
        return $list;
    }

    public  function get_mq_group_by_queue($queue, $cache = '')
    {

        $key = self::getCacheKey($queue, self::GROUP_INFO_DATA_KEY);
        $list = Cache::store('redis')->get($key);
        if (!$list) {
            $list = (new SystemMqGroupModel())->where(['queue_name' => $queue])->find();
            $list = objectToArray($list);
            Cache::store('redis')->set($key,$list,7200);
        }
        return $list;
    }


    /**
     * 通过分组id推送对应的数据到队列上
     * @param $mqObj
     * @param $groupId
     * @param $message
     * @return bool
     * @author xx
     * @Date 2024/3/12 17:13
     */
    public  function mq_send_message_by_group($mqObj, $groupId, $message)
    {

        try {
            $queueConfig  = self::get_mq_group_by_id($groupId);
            $queueName    = isset($queueConfig['queue_name']) ? $queueConfig['queue_name'] : '';
            $exchangeName = isset($queueConfig['exchange_name']) ? $queueConfig['exchange_name'] : '';
            $bindKeyName  = isset($queueConfig['bind_key']) ? $queueConfig['bind_key'] : '';
            ##如果mq对象参数没有传递，则根据分组id获取配置，重新创建连接
            if (empty($mqObj) || !is_object($mqObj)) {
                $mqObj = app(rabbitmq::class, [$queueConfig['mq_config']]);
            }

            $queueData['queue_name'] = $queueName;
            $queueData['exchange_name'] = $exchangeName;
            $queueData['bind_key'] = $bindKeyName;
            return $mqObj->mq_send_message($message, $queueData);
        } catch (\Exception $e) {

            return $e->getMessage();
        }

    }


    /**
     * 添加
     * @param $params
     * @return mixed
     * @author xx
     * @Date 2024/3/12 15:16
     */
    public function mq_group_add($params)
    {

        try {
            //验证器参数验证
            $res = (new SystemMqAdd())->check($params);
            if(!$res) return $this->jsonMessage(201, false, (new SystemMqAdd())->getError(), null);
            //判读是否存在
            $query = (new SystemMqGroupModel())
                ->whereOr('group_name',$params['group_name'])
                ->whereOr('queue_name',$params['queue_name']);
            $results = $query->select()->toArray();
            if($results) return $this->jsonMessage(201, false,'队列名或分组消息已经存在!', null);
            $is_exit_next =  (new SystemMqGroupModel())->where(['exchange_name' => $params['exchange_name'], 'bind_key' => $params['bind_key']])->find();
            if($is_exit_next) return $this->jsonMessage(201, false,"交换机名+绑定key不唯一", null);
            //默认禁用
            $params['create_time'] = time();
            $params['update_time'] = time();
            $res_id = (new SystemMqGroupModel())->insertGetId($params);
            if(!$res_id)  return $this->jsonMessage(201, false,'保存失败!', null);
            $key = self::getCacheKey($res_id, self::GROUP_INFO_DATA_KEY);
            Cache::store('redis')->delete($key);
            return $this->jsonMessage(200, true, "添加成功", null);
        } catch (\Exception $e) {
            return $this->jsonMessage(201, false, $e->getMessage(), null);
        }
    }


    /**
     * 编辑
     * @param $params
     * @return mixed
     * @author xx
     * @Date 2024/3/12 15:16
     */
    public function mq_group_edit($params)
    {
        try {
            //验证器参数验证
            $res = (new SystemMqAdd())->check($params);
            if(!$res) return $this->jsonMessage(201, false, (new SystemMqAdd())->getError(), null);
            //判读是否存在
            $query = (new SystemMqGroupModel())
                ->whereOr('group_name',$params['group_name'])
                ->whereOr('queue_name',$params['queue_name']);

            $is_exit = $query->find();
            $is_exit = objectToArray($is_exit);
            $is_exit_next =  (new SystemMqGroupModel())->where(['exchange_name' => $params['exchange_name'], 'bind_key' => $params['bind_key']])->field('id')->find();
            if (isset($is_exit['status']) && $is_exit['status'] == 2) {
                return $this->jsonMessage(201, false,"启用数据才能修改", null);
            }

            if(!isset($params['id']) || empty($params['id'])){
                return $this->jsonMessage(201, false,"ID不能为空!", null);

            }

            if (!empty($is_exit) && ($is_exit['id'] != $params['id'])) {
                return $this->jsonMessage(201, false,"名称或队列名不唯一", null);
            }

            if (!empty($is_exit_next) && ($is_exit_next['id'] != $params['id'])) {
                return $this->jsonMessage(201, false,"交换机名+绑定key不唯一", null);
            }

            $model             = (new SystemMqGroupModel())->where('id',$params['id'])->find();
            $old_exchange_name = $model->exchange_name;
            $old_bind_key      = $model->bind_key;
            $old_queue_name    = $model->queue_name;

            if (empty($model))     return $this->jsonMessage(201, false,"id:{$params['id']}数据不存在，请核实", null);
            $key_id = $params['id'];
            unset($params['id']);
            $params['update_time'] = time();
            $res = (new SystemMqGroupModel())->update($params,['id'=>$key_id]);
            if(!$res)    return $this->jsonMessage(201, false,"更新失败", null);
            $key = self::getCacheKey($key_id, self::GROUP_INFO_DATA_KEY);
            Cache::store('redis')->delete($key);

            ##修改成功得重新队列
            if ($old_exchange_name != $params['exchange_name'] || $old_bind_key != $params['bind_key'] || $old_queue_name != $params['queue_name']){
                #解绑
                $queueData['mq_config']     = $model->mq_config;
                $queueData['queue_name']    = $old_queue_name;
                $queueData['exchange_name'] = $old_exchange_name;
                $queueData['bind_key']      = $old_bind_key;
                $res = MqGroupLogic::mq_unbind_queue($queueData);
            }
            MqGroupLogic::mq_careate_queue($params);
            return $this->jsonMessage(200, true, "编辑成功", null);
        } catch (\Exception $e) {
            return $this->jsonMessage(201, false, $e->getMessage(), null);
        }
    }



    /**
     * @param $mark
     * @param $fun
     * @return string
     * @desc 处理key值
     */
    public function getCacheKey($mark,$fun){
        $original_class = trim(get_called_class(),'\\');   #原始调用类
        if (strrpos($original_class,'\\') !== false) $original_class = str_replace("\\",'.',$original_class);
        return $original_class.'.'.strtolower($fun).'_'.$mark;
    }


    /**
     * 队列-修改状态
     * @param $params
     * @return mixed
     * @author xx
     * @Date 2024/3/12 17:13
     */
    public function mq_group_status($params)
    {
        try {
            $res = (new SystemMqCheck())->check($params);
            if(!$res) return $this->jsonMessage(201, false, (new SystemMqCheck())->getError(), null);
            $model = (new SystemMqGroupModel())->where('id',$params['id'])->find()->toArray();
            if (empty($model)) return $this->jsonMessage(201, false, "id:{$params['id']}数据不存在，请核实", null);
            $key_id = $params['id'];unset($params['id']);
            $res = (new SystemMqGroupModel())->update($params,['id'=>$key_id]);
            if(!$res)  return $this->jsonMessage(201, false,"审核失败", null);
            $key = self::getCacheKey($key_id, self::GROUP_INFO_DATA_KEY);
            Cache::store('redis')->delete($key);
            ##审核成功得创建队列
            if ($params['status'] == 1) {
               $res = MqGroupLogic::mq_careate_queue($model);
               if($res)  return $this->jsonMessage(201, false, $res, null);
            }
            return $this->jsonMessage(200, true, "审核成功", null);
        } catch (\Exception $e) {
            return $this->jsonMessage(201, false, $e->getMessage(), null);
        }
    }



}